/*
 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 */

package org.box2dflash.common.math {
	import org.box2dflash.common.math.Mat22;

	/// A 2D column vector.
	public class Vec2 {
		public function Vec2(x_:Number = 0, y_:Number = 0):void {
			x = x_; 
			y = y_;
		};

		public function zero():void { 
			x = 0.0; 
			y = 0.0; 
		}

//		public function set (x_:Number = 0, y_:Number = 0):void {
//			x = x_; 
//			y = y_;
//		};

		public function v(v:Vec2):void {
			x = v.x; 
			y = v.y;
		};

		public function get negative():Vec2 { 
			return new Vec2(-x, -y); 
		}

		static public function make(x_:Number, y_:Number):Vec2 {
			return new Vec2(x_, y_);
		}

		public function get copy():Vec2 {
			return new Vec2(x, y);
		}

		public function add(v:Vec2):void {
			x += v.x; 
			y += v.y;
		}

		public function subtract(v:Vec2):void {
			x -= v.x; 
			y -= v.y;
		}

		public function multiply(a:Number):void {
			x *= a; 
			y *= a;
		}

		public function mulM(A:Mat22):void {
			var tX:Number = x;
			x = A.col1.x * tX + A.col2.x * y;
			y = A.col1.y * tX + A.col2.y * y;
		}

		public function mulTM(A:Mat22):void {
			var tX:Number = Box2dMath.dot(this, A.col1);
			y = Box2dMath.dot(this, A.col2);
			x = tX;
		}

		public function crossVF(s:Number):void {
			var tX:Number = x;
			x = s * y;
			y = -s * tX;
		}

		public function crossFV(s:Number):void {
			var tX:Number = x;
			x = -s * y;
			y = s * tX;
		}

		public function minV(b:Vec2):void {
			x = x < b.x ? x : b.x;
			y = y < b.y ? y : b.y;
		}

		public function maxV(b:Vec2):void {
			x = x > b.x ? x : b.x;
			y = y > b.y ? y : b.y;
		}

		public function abs():void {
			if (x < 0) x = -x;
			if (y < 0) y = -y;
		}

		public function get length():Number {
			return Math.sqrt(x * x + y * y);
		}

		public function get lengthSquared():Number {
			return (x * x + y * y);
		}

		public function get normalize():Number {
			var length:Number = Math.sqrt(x * x + y * y);
			if (length < Number.MIN_VALUE) {
				return 0.0;
			}
			var invLength:Number = 1.0 / length;
			x *= invLength;
			y *= invLength;
		
			return length;
		}

		public function get isValid():Boolean {
			return Box2dMath.isValid(x) && Box2dMath.isValid(y);
		}

		public var x:Number;
		public var y:Number;
	}
}